﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Hosting;
using Enter.Mvc.Base.Model;

namespace Enter.Mvc.Base.Skinning
{
	public class VirtualPathProviderSkinEngine :ISkinEngine
	{
		private static readonly string Sking = "~/Skins/";
		private static bool? SkingBool = null;
		private static IDictionary<string, string> HsSking = null;

        protected static string[] masterLocationFormats;

        protected static string[] viewLocationFormats;

		private readonly VirtualPathProvider virtualPathProvider;

		private readonly UnityBase _baseweb;

		/// <summary>
		/// 判断是否存在皮肤 文件夹
		/// </summary>
		private void GetSkingBool()
		{
			if (SkingBool == null)
			{
				if (virtualPathProvider.DirectoryExists(Sking))
				{
					SkingBool = true;
                    viewLocationFormats = new[]
                    {
		                "~/Skins/{2}/{1}/{0}.cshtml",
                        "~/Skins/{2}/{1}/{0}.aspx",
                        "~/Skins/{2}/{1}/{0}.ascx",
			            "~/Skins/{2}/Shared/{0}.cshtml",
                        "~/Skins/{2}/Shared/{0}.aspx",
                        "~/Skins/{2}/Shared/{0}.ascx",
		                "~/Views/{1}/{0}.cshtml",
                        "~/Views/{1}/{0}.aspx",
                        "~/Views/{1}/{0}.ascx",
		                "~/Views/Shared/{0}.cshtml",
                        "~/Views/Shared/{0}.aspx",
                        "~/Views/Shared/{0}.ascx"
                    };

                    masterLocationFormats = new[]
                    {
                        "~/Skins/{2}/{1}/{0}.cshtml",
			            "~/Skins/{2}/{1}/{0}.master",
                        "~/Skins/{2}/Shared/{0}.cshtml",
			             "~/Skins/{2}/Shared/{0}.master",
                        "~/Views/{1}/{0}.cshtml",
			            "~/Views/{1}/{0}.master",
                        "~/Views/Shared/{0}.cshtml",
			            "~/Views/Shared/{0}.master",
                    };
				}
				else
				{
					SkingBool = false;
                    viewLocationFormats = new[]
                    {
		                "~/Views/{1}/{0}.cshtml",
                        "~/Views/{1}/{0}.aspx",
                        "~/Views/{1}/{0}.ascx",
		                "~/Views/Shared/{0}.cshtml",
                        "~/Views/Shared/{0}.aspx",
                        "~/Views/Shared/{0}.ascx"
                    };

                    masterLocationFormats = new[]
                    {
                        "~/Views/{1}/{0}.cshtml",
			            "~/Views/{1}/{0}.master",
                        "~/Views/Shared/{0}.cshtml",
			            "~/Views/Shared/{0}.master",
                    };
				}
			}
		}

		public VirtualPathProviderSkinEngine(VirtualPathProvider virtualPathProvider, UnityBase site)
		{
			this.virtualPathProvider = virtualPathProvider;
			_baseweb = site;
			GetSkingBool();
			HsSking =new Dictionary<string, string>(100);
		}

		public virtual string FindMasterPath(string name, string folderName, out string[] locationsSearched)
		{
			return FindPath("Master", masterLocationFormats, name, folderName, out locationsSearched);
		}

		public virtual string FindViewPath(string name, string folderName, out string[] locationsSearched)
		{
			return FindPath("View", viewLocationFormats, name, folderName, out locationsSearched);
		}

		public virtual string FindPartialViewPath(string name, string folderName, out string[] locationsSearched)
		{
			return FindPath("View",viewLocationFormats, name, folderName, out locationsSearched);
		}

		protected string FindPath(string ViewName ,string[] locationsToSearch, string name, string folderName, out string[] locationsSearched)
		{
			locationsSearched = new string[locationsToSearch.Length];
			if (name.Length > 0)
			{
				string hanmae = string.Format("{0}_{1}_{2}",ViewName,folderName, name);
				if (!HsSking.ContainsKey(hanmae))
				{
					int locationCount = 0;
					foreach (string locationFormat in locationsToSearch)
					{
						string path = string.Format(locationFormat, name, folderName, _baseweb.SkinDefault);
						locationsSearched[locationCount++] = path;
						if (virtualPathProvider.FileExists(path))
						{
							HsSking.Add(hanmae, path);
							return path;
						}
					}
				}
				else
				{
					return HsSking[hanmae];
				}
			}
			return null;
		}

    }
}
